package com.xgst.smallscreen.http

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.JsonUtils
import com.blankj.utilcode.util.LogUtils
import com.hjq.http.EasyLog
import com.hjq.http.config.IRequestHandler
import com.hjq.http.exception.CancelException
import com.hjq.http.exception.DataException
import com.hjq.http.exception.HttpException
import com.hjq.http.exception.NullBodyException
import com.hjq.http.exception.ResponseException
import com.hjq.http.request.HttpRequest
import okhttp3.Headers
import okhttp3.Response
import okhttp3.ResponseBody
import java.io.IOException
import java.io.InputStream
import java.lang.reflect.GenericArrayType
import java.lang.reflect.Type
import java.net.ConnectException
import java.nio.charset.StandardCharsets

class RequestHandler : IRequestHandler {

    override fun requestSuccess(httpRequest: HttpRequest<*>, response: Response, type: Type): Any {

        if (Response::class.java == type) {
            return response
        }

        val responseBody = response.body
        val bodyString = responseBody?.string()

        if(response.code != 200){
            throw ResponseException("${response.code} : ${response.message}",response)
        }

        if (!response.isSuccessful) {
            val source = responseBody!!.source()
            source.request(Long.MAX_VALUE)
            val buffer = source.buffer()
            val resultString = buffer.clone().readString(StandardCharsets.UTF_8)
            //throw ResponseException("code: ${response.code()}\n$resultString",response)
            val text: String = bodyString?:"bodyString异常"
            return text
        }
        if (Headers::class.java == type) {
            return response.headers
        }

        val body = response.body ?: throw NullBodyException("ResponseBody为空")

        if (ResponseBody::class.java == type) {
            LogUtils.file("${httpRequest.requestApi}\n${bodyString}")
            return body
        }

        // 如果是用数组接收，判断一下是不是用 byte[] 类型进行接收的
        if (type is GenericArrayType) {
            val genericComponentType = type.genericComponentType
            if (Byte::class.javaPrimitiveType == genericComponentType) {
                return body.bytes()
            }
        }

        if (InputStream::class.java == type) {
            return body.byteStream()
        }

        if (Bitmap::class.java == type) {
            return BitmapFactory.decodeStream(body.byteStream())
        }

        val text: String = bodyString?:"bodyString异常"

        // 打印这个 Json 或者文本
        EasyLog.printJson(httpRequest, text)
        LogUtils.file("${httpRequest.requestHost.host+httpRequest.requestApi.api}\n$text")

        if (String::class.java == type) {
            return text
        }

        val result: Any

        result = try {
            GsonUtils.fromJson<Any>(text, type)
        } catch (e: Exception) {
            LogUtils.file("${httpRequest.requestApi.api}\n数据解析异常")
            // 返回结果读取异常
            throw DataException("数据解析异常", e)
        }

        val code = JsonUtils.getInt(text, "code")
        val msg = JsonUtils.getString(text, "msg")

        return if (code == 200 || code == 500 || code == 404 || code == 400) {
            // 代表执行成功
            result
        }else{
            throw Exception(msg)
        }
    }

    override fun requestFail(
        httpRequest: HttpRequest<*>,
        e: java.lang.Exception
    ): java.lang.Exception {
        if (e is HttpException) {
            return e
        }

        if (e is ConnectException) {
            return ConnectException("无法连接服务器 " + e.message)
        }

        return if (e is IOException) {
            CancelException("IO异常：${e.message}", e)
        } else{
            HttpException(e.message, e)
        }
    }
}